package com.jxpay.yspay;

import com.jxpay.yspay.core.HttpClientUtil;
import com.jxpay.yspay.core.SignUtils;
import com.jxpay.yspay.core.StringUtils;
import com.jxpay.yspay.enums.YsApiType;
import com.jxpay.yspay.enums.YsDomain;

import cn.hutool.core.date.DateUtil;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>JXPay-银盛支付</p>
 *
 * @author JX
 */
public class YsPayApi {

    private YsPayApi() {
    }

    /**
     * 获取接口请求的method
     *
     * @param ysApiType {@link YsApiType} 支付 API 接口枚举
     * @return {@link String} 返回完整的接口请求method
     */
    public static String getReqMethod(YsApiType ysApiType) {
        return getReqMethod(ysApiType,  false);
    }

    /**
     * 获取接口请求的method
     *
     * @param ysApiType {@link YsApiType} 支付 API 接口枚举
     * @param ysDomain  {@link YsDomain} 支付 API 接口域名枚举
     * @param isSandBox 是否是沙箱环境
     * @return {@link String} 返回完整的接口请求method
     */
    public static String getReqMethod(YsApiType ysApiType, boolean isSandBox) {
        return ysApiType.getType()
                .concat(isSandBox ? YsApiType.SAND_BOX_NEW.getType() : "");
    }
    
    public static String doGet(String url, Map<String, String> params) {
        return HttpClientUtil.sendPost(url, params);
    }

    public static String doPost(String url, Map<String, String> params) {
        return HttpClientUtil.sendPost(url, params);
    }
    /**
     * 发起请求
     *
     * @param apiUrl 接口 URL
     *               通过 {@link YsPayApi#getReqUrl(YsApiType)}
     *               或者 {@link YsPayApi#getReqUrl(YsApiType, YsDomain, boolean)} 来获取
     * @param params 接口请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String execution(String apiUrl, Map<String, String> params) {
        return doPost(apiUrl, params);
    }

    /**
     * 发起请求
     *
     * @param apiUrl 接口 URL
     *               通过 {@link YsPayApi#getReqUrl(YsApiType)}
     *               或者 {@link YsPayApi#getReqUrl(YsApiType, YsDomain, boolean)} 来获取
     * @param params 接口请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String executionByGet(String apiUrl, Map<String, String> params) {
        return doGet(apiUrl, params);
    }



    /**
     * V3 接口统一执行入口
     *
     * @param method    {@link Method} 请求方法
     * @param urlPrefix 可通过 {@link YsDomain}来获取
     * @param mchId     商户Id
     * @param serialNo  商户 API 证书序列号
     * @param keyPath   apiclient_key.pem 证书路径
     * @param body      接口请求参数
     * @param nonceStr  随机字符库
     * @param timestamp 时间戳
     * @param authType  认证类型
     * @return {@link String} 请求返回的结果
     * @throws Exception 接口执行异常
     */
    public static String v3Execution(YsDomain urlPrefix,String method, String partnerId, String charset, String signType, String notifyUrl, String version,String pfxCertFile,String pfxPasswd,Map<String,String> bizContent) throws Exception {
        Map<String, String> paramsMap = new HashMap<String, String>();
        paramsMap.put("method",method);
        paramsMap.put("partner_id",partnerId);
        paramsMap.put("timestamp", DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        paramsMap.put("charset",charset);
        paramsMap.put("sign_type",signType);
        paramsMap.put("notify_url",notifyUrl);
        paramsMap.put("version",version);        
        paramsMap.put("biz_content",StringUtils.toJson(bizContent));        
        //构建签名参数
        paramsMap.put("sign", SignUtils.rsaSign(paramsMap,charset,pfxPasswd,pfxCertFile));
        System.out.println("请求："+urlPrefix.getType()+" 参数："+paramsMap);
        return execution(urlPrefix.getType(),paramsMap);
    }

    public static String apiPay(YsDomain ysDomain,String method,YsPayApiConfig ysConfig, Map<String, String> params) {   	
        if (ysDomain == null) {
        	ysDomain = YsDomain.CHINA;
        }
    	try {
			return v3Execution(ysDomain,method,ysConfig.getPartnerId(), ysConfig.getCharset(),ysConfig.getSignType(),ysConfig.getNotifyUrl(),ysConfig.getVer(),ysConfig.getCertPath(),ysConfig.getCertPass(),params);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return null;
		}
    }
    
    public static String apiPay(String method,YsPayApiConfig ysConfig, Map<String, String> params) {   	
        return apiPay(null,method,ysConfig,params);
    }
    
    public static String apiPay(String method,Map<String, String> params) {   	
        return apiPay(null,method,YsPayApiConfigKit.getYsPayApiConfig(),params);
    }    
    
    /**
     * 刷卡支付
     *
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String microPay(Map<String, String> params) {   	
        return apiPay(getReqMethod(YsApiType.MICRO_PAY),params);
    }    
    /**
     * 订单查询
     *
     * @param params 请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderQuery(Map<String, String> params) {
        return orderQuery(false,  params);
    }
    
    /**
     * 订单查询
     *
     * @param isSandbox 是否是沙盒环境
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderQuery(boolean isSandbox, Map<String, String> params) {
        return apiPay(getReqMethod(YsApiType.ORDER_QUERY, isSandbox), params);
    }

    /**
     * 查询退款
     *
     * @param isSandbox 是否是沙盒环境
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderRefundQuery(Map<String, String> params) {
        return apiPay(getReqMethod(YsApiType.REFUND_QUERY, false), params);
    }

    /**
     * 查询退款
     *
     * @param isSandbox 是否是沙盒环境
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderRefundQuery(boolean isSandbox, Map<String, String> params) {
        return apiPay(getReqMethod(YsApiType.REFUND_QUERY, isSandbox), params);
    }



    public static void main(String[] args) {
    	YsPayApiConfig ys =YsPayApiConfig.builder().appId("826581173720001")
    			.partnerId("826581173720001")
    			.charset("GBK")
    			.signType("RSA")
    			.ver("3.0")
    			.notifyUrl("http://data.jiangxinit.com/pay/notify/ys/callbak")
    			.certPath("F:\\yspay\\yspay_merchant\\cert\\ys.pfx")
    			.certPass("815815")
    			.build();
    	YsPayApiConfigKit.putApiConfig(ys);
        System.out.println(setBarcodePay());
    }

    public static String setBarcodePay() {
        Map<String,String> bizContent = new HashMap<>();
        bizContent.put("shopdate", DateUtil.format(new Date(),"yyyyMMdd"));
        bizContent.put("total_amount", "0.01");
        bizContent.put("seller_id", "826581173720001");
        bizContent.put("seller_name", "广州匠心互动科技有限公司");
        bizContent.put("out_trade_no", "2020020500240002");
        bizContent.put("subject", "条码支付测试");
        bizContent.put("timeout_express", "1d");
        bizContent.put("bank_type", "1902000");
        bizContent.put("business_code", "01000010");
        bizContent.put("auth_code", "134658589963125937");
        String response =YsPayApi.microPay(bizContent);
        System.out.println("结果：:"+response);
        //银盛回调信息:{"notify_time":"2020-02-05 19:01:41","payee_fee":"0.00","account_date":"20200205","openid":"oVWdhs8ZM_9O0dJG8v0QPjY-TS8o","fee":"0.00","sign":"oODuFAyUFU7xpqn3YDuunp3ZU1r7D111zfzicxB3mTHYGx9GqSL8/UHso1jdC6gimVnwhxsNmipbpmHd3BqtUP4aEHKTRuyT6ZDwba14Ln5HyATXbXShrS+baA9iqS9FUfREdor7CzX1m0brNXRx5y7VdJTOIcZ+RjliijJcTos=","channel_send_sn":"1012002058897565271","card_type":"","notify_type":"directpay.status.sync","partner_fee":"0.00","out_trade_no":"2020020500240002","total_amount":"0.01","trade_status":"TRADE_SUCCESS","trade_no":"01O200205889756527","settlement_amount":"0.01","paygate_no":"9000010","sign_type":"RSA","payer_fee":"0.00","channel_recv_sn":"4200000496202002052970879207"}        
        return "";

    }    
}
